
import time
import sys
import getpass
import _acquirepy as acquirepy

acquirepy.acquireCommonInitLibraries()
brokername = "broker"
bhost = "127.0.0.1"
bport = 10000
bpassword = ""
username = ""
directory = "/tmp"
subjectactor = ""
handleactor = ""
do_ssh_add = 0
do_submit_dir = 0
do_get_results = 0
do_dump_tree = 0
ssh_user_at_machine = ""
for i in range(len(sys.argv)):
   targ = sys.argv[i]
   if ((targ[0] == '-') and (targ[1] != '-')):
      if (targ[1] == 'b'): brokername = sys.argv[i+1]
      if (targ[1] == 'n'): bhost = sys.argv[i+1]
      if (targ[1] == 'p'): bport = int(sys.argv[i+1])
      if (targ[1] == 't'): bpassword = sys.argv[i+1]
      if (targ[1] == 'u'): username = sys.argv[i+1]
      if (targ[1] == 'd'): directory = sys.argv[i+1]
      if (targ[1] == 's'): subjectactor = sys.argv[i+1]
      if (targ[1] == 'r'): handleactor = sys.argv[i+1]
      if (targ[1] == 'm'): ssh_user_at_machine = sys.argv[i+1]
      if (targ[1] == 'A'): do_ssh_add = 1
      if (targ[1] == 'S'): do_submit_dir = 1
      if (targ[1] == 'D'): do_get_results = 1
      if (targ[1] == 'T'): do_dump_tree = 1

blocksize = 1048576
retcode = acquirepy.acquireClientInitState(bhost, bport, username, username, bpassword, brokername)
if (retcode == 0):
   print("Error encountered while setting initial client state. Check log for possible reasons.")
   exit(1)
retcode = acquirepy.acquireClientRegisterUserWithBroker()
if (retcode == 3):
   print("Invalid username")
   exit(1)
if (do_ssh_add):
   print("Adding SSH credentials for %s" % ssh_user_at_machine)
   ssh_password = getpass.getpass("SSH password: ")
   retval = acquirepy.acquireClientAddSSHHost(ssh_user_at_machine, ssh_password, None, None)
   if (retval == 1): print("Successfully added this machine to Acquire.")
   elif (retval == 2): print("ACCESS DENIED: The fingerprint of this machine is untrusted by the requested broker, and adding this machine could be a security risk. Please contact your administrator")
   elif (retval == 3): print("ERROR: Could not reach the target machine.")
   elif (retval == 4): print("ACCESS DENIED: Access denied. Please check your credentials were typed correctly.")
   else: print("ERROR: Unknown error or failure occurred.\n")
if (retcode == 1):
   if (do_submit_dir):
      print("Creating new datastore...");
      work_datastore_info = acquirepy.acquirePythonCreateDataStore(directory, None, None, 1, blocksize)
      if (acquirepy.acquirePythonGetDSIsValid(work_datastore_info)):
         print("Datastore is created and valid")
         work_datastore_name = acquirepy.acquirePythonGetDSName(work_datastore_info)
         work_datastore_blockcount = acquirepy.acquirePythonGetDSBlockCount(work_datastore_info)
         keyname_encrypting = '%s_inp' % work_datastore_name
         print("Beginning upload...")
         retcode = acquirepy.acquirePythonUploadToDataStore(work_datastore_name, directory, blocksize, keyname_encrypting)
         if (retcode == 0):
            print("Upload of data to datastore complete...")
            retcode = acquirepy.acquireCommonSetPurposeFlagsOnDataStore(work_datastore_name, 1, 0, None, 60 * 60 * 24, 1, bpassword)
            if (retcode == 1):
               print("Marked the completed uploaded data as work to be run")
            elif (retcode == -1):
               print("ERROR: Broker could not start the work")
            else:
               print("ERROR: Could not mark the uploaded data")
         else:
            print("ERROR: Upload failed")
      else:
         print("ERROR: Problem creating or receiving datastore information.")
   if (do_get_results):
      if (subjectactor == ""):
         subjectactor = acquirepy.acquireCommonResolve(handleactor)
      if (subjectactor == None):
         print("Given store empty, inaccessible or not found.")
      print("Getting information about datastore...");
      results_datastore_info = acquirepy.acquireCommonGetDataStoreInformation(subjectactor)
      print("Obtained datastore metadata...");
      decryptionkey = acquirepy.acquirePythonGetDSDecryptionKey(results_datastore_info)
      blockcount = acquirepy.acquirePythonGetDSBlockCount(results_datastore_info)
      blocksize = acquirepy.acquirePythonGetDSBlockSize(results_datastore_info)
      instancecount = acquirepy.acquirePythonGetDSInstanceCount(results_datastore_info)
      isworkpacket = acquirepy.acquirePythonGetDSIsWorkPacket(results_datastore_info)
      isresults = acquirepy.acquirePythonGetDSIsResults(results_datastore_info)
      iscomplete = acquirepy.acquirePythonGetDSIsComplete(results_datastore_info)
      isvalid = acquirepy.acquirePythonGetDSIsValid(results_datastore_info)
      if (isvalid == 1):
         print("Downloading from datastore...")
         acquirepy.acquireCommonDeferredDownloadFromDataStore(subjectactor, "/tmp/", blockcount, None)
         print("Download complete.")
         print("Reconstructing data from stream...")
         acquirepy.acquireCommonReconstructDeferredDownload(subjectactor, "/tmp/", directory, blockcount, decryptionkey)
         print("Reconstructed files from data stream into %s" % directory)
      else:
         print("Datastore metadata invalid")
   if (do_dump_tree):
      print("Resolving tree of active items...")
      user_resname = acquirepy.acquireCommonResolve(username);
      if (user_resname == None):
         print("Invalid or non-existant username")
         exit(1)
      resstack = [username];
      outlist = [];
      while (len(resstack) > 0):
         item = resstack.pop()
         res = acquirepy.acquireCommonResolve(item + ".childrennames")
         if (res != None):
            splitres = res.split(",")
            for child in splitres:
               resstack = resstack + [item + "." + child]
         thisitem_progress = acquirepy.acquireCommonResolve(item + ".progress")
         thisitem_realid = acquirepy.acquireCommonResolve(item + ".id")
         thisitem_type = acquirepy.acquireCommonResolve(item + ".type")
         thisitem_localname = acquirepy.acquireCommonResolve(item + ".localname")
         if (thisitem_progress == None):
            t_progress = ""
         elif (thisitem_progress == "-1.0"):
            t_progress = "(progress error)"
         else:
            if (thisitem_type == "datastores"):
               cprog = float(thisitem_progress);
               if (cprog == 0.0):
                  t_progress = "waiting for client upload"
               elif (cprog == 1.0):
                  t_progress = "upload complete"
               else:
                  t_progress = "uploading at %01d.%01d%% complete" % ((int(cprog * 1000.) / 10), (int(cprog * 1000.) % 10))
            elif (thisitem_type == "workinstances"):
               cprog = float(thisitem_progress);
               if (cprog == 0.0):
                  t_progress = "not running"
               elif (cprog == 1.0):
                  t_progress = "finished"
               else:
                  t_progress = "running at %01d.%01d%% complete" % ((int(cprog * 1000.) / 10), (int(cprog * 1000.) % 10))
            else:
               t_progress = ""
         outlist = outlist + [[item.count("."), thisitem_localname, thisitem_realid, t_progress]]
      for entrylist in outlist:
         print((" " * (entrylist[0] * 3)) + str(entrylist[1]) + " - " + str(entrylist[3]))
#         print((" " * (entrylist[0] * 3)) + str(entrylist[1]) + " (" + str(entrylist[2]) + ")   " + str(entrylist[3]))
else:
   if (do_submit_dir):
      print("DENIED: Can't submit directory: user not recognised")

acquirepy.acquireCommonDestroyState()
acquirepy.acquireCommonDestroy()

# cp ../repos/branches/devel/scripts/user.py ./
# python ./user.py -b broker -u test -n 127.0.0.1 -p 10000 -t hello -m benlong@127.0.0.1 -A
# python ./user.py -b broker -u test -n 127.0.0.1 -p 10000 -t hello -d ../zebed_workpacketA_test/ -S
# python ./user.py -b broker -u test -n 127.0.0.1 -p 10000 -t hello -s test -F
# mkdir -p /tmp/zebed_workpacketA_test/
# python ./user.py -b broker -u test -n 127.0.0.1 -p 10000 -t hello -d /tmp/zebed_workpacketA_test/ -s <resultdatastore> -D

# can be automated in one script, if you get the children of the datastore, giving you the workinstances
# (that are known to have all be created when SetPurposeFlags returned)
# so, check each workinstance to find a child datastore - which is necessarily the workinstance result
